package com.lantosec.hmrp.modules.login.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lantosec.hmrp.core.config.InitDataListener;
import com.lantosec.hmrp.core.kit.Result;
import com.lantosec.hmrp.core.shiro.TokenUtil;
import com.lantosec.hmrp.core.util.RedisUtils;
import com.lantosec.hmrp.core.util.UUIDUtils;
import com.lantosec.hmrp.modules.login.service.ILoginService;
import com.lantosec.hmrp.modules.system.entity.*;
import com.lantosec.hmrp.modules.system.mapper.SysUserMapper;
import com.lantosec.hmrp.modules.system.service.*;
import com.lantosec.hmrp.modules.system.vo.*;
import com.lantosec.hmrp.modules.uploads.entity.SysUploads;
import com.lantosec.hmrp.modules.uploads.service.ISysUploadsService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

@Service
@Primary
@SuppressWarnings("all")
public class LoginServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements ILoginService {
    @Autowired
    private ISysUserService userService;

    @Autowired
    private ISysRoleService roleService;

    @Autowired
    private ISysMenuService sysMenuService;

    @Autowired
    private ISysUploadsService sysUploadsService;

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private IUserAutographService iUserAutographService;

    @Autowired
    private ISysParameterService iSysParameterService;

    @Autowired
    private ISysDeptService iSysDeptService;

    @Autowired
    private ISysMenuService iSysMenuService;

    @Autowired
    private ISysLoginLogService sysLoginLogService;


    @Override
    public Result login(String userName, String password, HttpServletResponse response, HttpServletRequest request) {
        Result res = null;
        SysUser user = userService.getBaseMapper().selectOne(new QueryWrapper<SysUser>()
                .eq(String.valueOf(SysUser.ColName.username), userName));
        if (null == user) {
            return Result.fail("未知的用户名");
        }
        String pw = user.getPassword();
        if (!pw.equals(password)) {
            return Result.fail("密码错误");
        }
        res = getLoginInfo(response, user);

        // 记录登录日志
        saveLoginLog(request.getRemoteAddr(), user.getUserId());
        return res;
    }

    //获取登录用户角色、权限、菜单等信息
    private Result getLoginInfo(HttpServletResponse response, SysUser user) {
        List<String> permissionList = null;
        Result res;//返回用户头像路径
        SysUserVO sysUserVO = user.convertToVO();
        if (StringUtils.isNotEmpty(sysUserVO.getPicture())) {
            SysUploads sysUploads = sysUploadsService.getById(sysUserVO.getPicture());
            sysUserVO.setSavePath(InitDataListener.uploadsUrl + sysUploads.getSavePath() + sysUploads.getFileName());
        }

        //查询用户角色
        List<SysRoleVO> roles = userService.queryRoleByUserId(user.getUserId());
        List<SysPermissionVO> permissions = new ArrayList<>();
        roles.forEach(role -> {
            permissions.addAll(roleService.queryPermissionByRuleId(role.getRoleId()));
        });

        //部门岗位信息
        SysDeptUser deptUser = userService.getDeptInfo(user.getUserId());
        if (!Objects.isNull(deptUser)) {
            sysUserVO.setDeptId(deptUser.getDeptId());
            sysUserVO.setDeptName(deptUser.getDeptName());
            sysUserVO.setPositionId(deptUser.getPositionId());
            sysUserVO.setPositionName(deptUser.getPositionName());
            user.setDeptId(deptUser.getDeptId());
        }

        //查询系统参数表数据
        List<SysParameter> sysParameters = iSysParameterService.list();

        //查询用户签名
        UserAutographVO userAutographVO = iUserAutographService.getByUserId(user.getUserId());
        if (Objects.isNull(userAutographVO)) {
            userAutographVO = new UserAutographVO();
        }
        Long currentTimeMillis = System.currentTimeMillis();
        String token = TokenUtil.sign(user, currentTimeMillis);
        redisUtils.set(user.getUserId(), currentTimeMillis, TokenUtil.REFRESH_EXPIRE_TIME);
        response.setHeader("Authorization", token);
        response.setHeader("Access-Control-Expose-Headers", "Authorization");
        LoginVO loginVO = new LoginVO(sysUserVO, permissions, sysParameters, userAutographVO);
        res = Result.ok(loginVO);
        return res;
    }

    @Override
    public Result avoidCloseLogin(SysUser param, HttpServletResponse response, HttpServletRequest request) {
        SysUser user = userService.getBaseMapper().selectOne(new QueryWrapper<SysUser>()
                .eq(String.valueOf(SysUser.ColName.user_id), param.getUserId()));
        if(Objects.isNull(user)){
            return Result.fail("未知的用户名");
        }
        //返回用户头像路径
        Result res = getLoginInfo(response, user);

        // 记录登录日志
        saveLoginLog(request.getRemoteAddr(), user.getUserId());
        return res;
    }

    @Override
    public List<SysDeptUser> getDeptAndPositionList(String userId) {
        return userService.getDeptAndPositionList(userId);
    }

    @Override
    public Result loginSuper(String userName, String passWord, HttpServletResponse response, HttpServletRequest request) {
        Result res = null;
        SysUser user = userService.getBaseMapper().selectOne(new QueryWrapper<SysUser>()
                .eq(String.valueOf(SysUser.ColName.username), userName));
        if (null == user) {
            return Result.fail("未知的用户名");
        }
        String pw = user.getPassword();
        if (!pw.equals(passWord)) {
            return Result.fail("密码错误");
        }
        res = getLoginInfoSuper(response, user);

        // 记录登录日志
        saveLoginLog(request.getRemoteAddr(), user.getUserId());
        return res;
    }

    @Override
    public Result choicePositionLogin(SysUser user, HttpServletResponse response, HttpServletRequest request) {
        String userId = TokenUtil.getUserId();
        SysUser sysUser = userService.getById(userId);
        SysUserVO sysUserVO = sysUser.convertToVO();
        //查询用户头像信息
        if (StringUtils.isNotEmpty(sysUserVO.getPicture())) {
            SysUploads sysUploads = sysUploadsService.getById(sysUserVO.getPicture());
            sysUserVO.setSavePath(InitDataListener.uploadsUrl + sysUploads.getSavePath() + sysUploads.getFileName());
        }

        //查询用户角色
        List<SysRoleVO> roles = userService.queryRoleByUserId(user.getUserId());
        List<SysPermissionVO> permissions = new ArrayList<>();
        roles.forEach(role -> {
            permissions.addAll(roleService.queryPermissionByRuleId(role.getRoleId()));
        });
        sysUserVO.setDeptId(user.getDeptId());
        sysUserVO.setPositionId(user.getPositionId());
        //查询系统参数表数据
        List<SysParameter> sysParameters = iSysParameterService.list();

        //查询用户签名
        UserAutographVO userAutographVO = iUserAutographService.getByUserId(user.getUserId());
        if (Objects.isNull(userAutographVO)) {
            userAutographVO = new UserAutographVO();
        }
        Long currentTimeMillis = System.currentTimeMillis();
        String token = TokenUtil.sign(user, currentTimeMillis);
        redisUtils.set(user.getUserId(), currentTimeMillis, TokenUtil.REFRESH_EXPIRE_TIME);
        response.setHeader("Authorization", token);
        response.setHeader("Access-Control-Expose-Headers", "Authorization");
        LoginVO loginVO = new LoginVO(sysUserVO, permissions, sysParameters, userAutographVO);
        Result res = Result.ok(loginVO);
        return res;
    }

    private Result getLoginInfoSuper(HttpServletResponse response, SysUser user) {
        Result res;
        SysUserVO sysUserVO = user.convertToVO();
        //查询所有的部门岗位
        SysDept sysDept = iSysDeptService.list(new QueryWrapper<>()).get(0);
        sysUserVO.setDeptId(sysDept.getDeptId());
        sysUserVO.setDeptName(sysDept.getDeptName());
        //查询系统参数表数据
        List<SysParameter> sysParameters = iSysParameterService.list();
        //返回菜单
        List<SysMenusVO> sysMenusVOS = iSysMenuService.getAllMenu(null);

        Long currentTimeMillis = System.currentTimeMillis();
        user.setDeptId(sysDept.getDeptId());
        String token = TokenUtil.sign(user, currentTimeMillis);
        redisUtils.set(user.getUserId(), currentTimeMillis, TokenUtil.REFRESH_EXPIRE_TIME);
        response.setHeader("Authorization", token);
        response.setHeader("Access-Control-Expose-Headers", "Authorization");
        LoginVO loginVO = new LoginVO(sysUserVO, sysParameters, sysMenusVOS);
        res = Result.ok(loginVO);
        return res;
    }

    /**
     * 保存登录日志
     *
     * @param ip
     * @param userId
     */
    private void saveLoginLog(String ip, String userId) {
        SysLoginLog loginLog = new SysLoginLog();
        loginLog.setLogId(UUIDUtils.get());
        loginLog.setLogIp(ip);
        loginLog.setLogUserId(userId);
        loginLog.setLogTime(new Date());
        sysLoginLogService.save(loginLog);
    }
}
